2 #Copyright 2010 Paul Hänsch
4 #This file is part of Viper.
6 #Viper is free software: you can redistribute it and/or modify
7 #it under the terms of the GNU General Public License as published by
8 #the Free Software Foundation, either version 3 of the License, or
9 #(at your option) any later version.
11 #Viper is distributed in the hope that it will be useful,
12 #but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 #GNU General Public License for more details.
16 #You should have received a copy of the GNU General Public License
17 #along with Viper. If not, see <http://www.gnu.org/licenses/>
25 Video player for inclusion in videoview widget
27 def __init__(self, parent, surface, callback = None, slider = None):
31 surface - the widget which shall be the parent for
33 callback - a function which is called on status change
34 the function will be called with a string parameter
35 beeing one of "playing", "paused", or "stopped"
36 slider - a Tk slider widget which controls and displays
37 the position in the video
40 self.surface = surface
41 self.announce_status = callback
43 self.slave = (None, None)
44 self.status = 'stopped'
48 if self.slider != None: self.slider.configure(command = self.s_seek)
51 def configure(self, surface = None, callback = None, slider = None):
52 if surface != None: self.surface = surface
53 if callback != None: self.announce_status = callback
56 self.slider.configure(command = self.s_seek)
58 def get_position(self):
60 Command mplayer slave to print position data
62 if self.slave != (None, None) and self.status == 'playing':
63 self.slave[0].writelines(['get_percent_pos\n'])
64 self.slave[0].writelines(['get_time_pos\n'])
66 try: self.slider.set(self.perc_pos /100, self.perc_pos /100 + .01)
68 self.parent.after(20, self.get_position)
70 def seek(self, absolute, pos):
74 absolute - True for absolute seek
75 False for relative seek
78 if self.slave != (None, None):
80 self.slave[0].writelines(['pausing seek '+ str(pos) + ' 1\n'])
81 self.status = 'paused'
82 self.announce_status(self.status)
84 self.slave[0].writelines(['pausing seek '+ str(pos) + ' 0\n'])
85 self.status = 'paused'
86 self.announce_status(self.status)
89 self.slave[sid][0].writelines(['pausing get_percent_pos\n'])
90 self.slave[sid][0].writelines(['pausing get_time_pos\n'])
91 self.slave[sid][0].flush()
95 def s_seek(self, p1 = None, p2 = None, p3 = None):
97 Callback for slider bar
99 Specify this function as the callback for a sliderbar
100 and the slider will control the video position
103 self.seek(True, int(p2[2:4]))
104 elif p1 == 'scroll' and p3 == 'units':
105 self.seek(False, int(p2) * 10)
106 elif p1 == 'scroll' and p3 == 'pages':
107 self.seek(False, int(p2) * 60)
109 def stop_video(self):
111 Stop playback of a video
113 if self.slave != (None, None):
114 self.slave[0].writelines(['stop\n'])
115 self.slave[0].flush()
116 self.status = 'stopped'
117 self.announce_status(self.status)
119 def play_video(self, loop = False, params = []):
123 surface - widget in which the video will be displayed
124 loop - if True loop the video indefinitely
125 params - list of playback parameters (filenames, filters, ...)
127 if self.slave == (None, None):
128 cmd = ['mplayer', '-slave', '-fixed-vo', '-osdlevel', '3', '-vo', 'x11',
129 '-wid', str(self.surface.winfo_id()), '-x','320', '-y','240']
130 if loop: cmd.extend(['-loop', '0'])
132 self.slave = os.popen2(cmd)
133 threading.Thread(target = self.read_slave).start()
135 self.slave[0].writelines(['seek 0\n'])
136 self.slave[0].flush()
137 self.status = 'playing'
138 self.announce_status(self.status)
140 def pause_video(self):
142 Pause video allowing resume
144 self.slave[0].writelines(['pause\n'])
145 self.slave[0].flush()
146 self.status = 'paused'
147 self.announce_status(self.status)
149 def read_slave(self):
151 Read output line of slave and
152 set time positions, etc...
155 perc_pos = time_pos = 0.0
156 while statline != '':
157 statline = self.slave[1].readline()
158 if statline.find('ANS_PERCENT_POSITION') != -1:
159 pos = statline[statline.find('ANS_PERCENT_POSITION'):]
161 perc_pos = float(pos.split('=')[1])
164 elif statline.find('ANS_TIME_POSITION') == 0:
165 pos = statline[statline.find('ANS_TIME_POSITION'):]
167 time_pos = float(pos.split('=')[1])
170 self.perc_pos = perc_pos
171 self.time_pos = time_pos
173 self.slave = (None, None)
174 self.status = 'stopped'
175 self.announce_status(self.status)
176 self.perc_pos = self.pre_perc_pos = 0
177 self.time_pos = self.pre_time_pos = 0
179 def step_video(self):
183 if self.slave != (None, None):
184 self.slave[0].writelines(['pausing frame_step\n'])
185 self.slave[0].flush()
186 self.status = 'paused'
187 self.announce_status(self.status)